package net.hn.hnms.biz.mine.service;

import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import net.hn.hnms.biz.api.mine.RemoteEquipmentService;
import net.hn.hnms.biz.api.mine.model.AlarmMessageItemVo;
import net.hn.hnms.biz.api.safety.location.fegin.RemoteLocationService;
import net.hn.hnms.biz.api.safety.monitor.fegin.RemoteMonitorService;
import net.hn.hnms.biz.mine.config.WeChatProperties;
import net.hn.hnms.biz.mine.domain.AlarmMessageLog;
import net.hn.hnms.biz.api.mine.model.WeChartBaseMessage;
import net.hn.hnms.biz.mine.domain.WeChartMessage;
import net.hn.hnms.biz.mine.repository.WeChartMessageRepository;
import net.hn.hnms.sys.common.core.domain.R;
import net.hn.hnms.sys.common.redis.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartboot.socket.MessageProcessor;
import org.smartboot.socket.transport.AioQuickClient;
import org.smartboot.socket.transport.AioSession;
import org.smartboot.socket.transport.WriteBuffer;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

/**
 * 智呈物联 pan'sx
 * 2022/9/2 14:29
 * 1.0 version
 */
@Service
@RequiredArgsConstructor
public class MessageServiceImpl implements MessageService {
    public static final String ACCESS_TOKEN = "WECHAT_ACCESS_TOKEN";
    private final static Logger logger = LoggerFactory.getLogger(MessageServiceImpl.class);
    private final RestTemplate restTemplate;
    private final WeChatProperties weChatProperties;
    private final WeChartMessageRepository weChartMessageRepository;
    private final RemoteLocationService remoteLocationService;
    private final RemoteMonitorService remoteMonitorService;
    private final RemoteEquipmentService remoteEquipmentService;
    public static volatile AioQuickClient client = null;
    public static AioSession session = null;

    @Override
    public WeChartMessage sendMessage(WeChartMessage msg) throws Exception {

        if ("单兵设备".equals(msg.getPublishSys())) {
            if (!msg.getStationCodes().isEmpty()) {
                R<List<String>> userIds = remoteLocationService.getUserIds(msg.getStationCodes());
                if (200 == userIds.getCode()) {
                    msg.getUserIds().addAll(userIds.getData());
                }
            }
            if (msg.getUserIds().isEmpty()) {
                throw new Exception("没有匹配到接收人。");
            } else {
                msg.setToUsers(StringUtils.join(msg.getUserIds(), "|"));
            }
            String accessToken = getAccessToken(weChatProperties.getCorpId(), weChatProperties.getCorpSecret());
            Map paramMap = new HashMap();
            paramMap.put("touser", msg.getToUsers());
            paramMap.put("agentid", weChatProperties.getAgentId());
            paramMap.put("text", new HashMap() {{
                put("content", msg.getEarlyWarnText());
            }});
            paramMap.put("msgtype", "text");
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            JSONObject jsonObject = new JSONObject(paramMap);
            HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), headers);
            JSONObject respnose = restTemplate.postForObject(String.format(weChatProperties.getSendMessageUrl(), accessToken), request, JSONObject.class);
            logger.info(respnose.toJSONString());
            msg.setWeChartResponse(respnose.toJSONString());
        } else if ("应急广播".equals(msg.getPublishSys())) {
            if (msg.getUserIds().isEmpty()) {
                throw new Exception("没有匹配到接收设备。");
            } else {
                msg.setToUsers(StringUtils.join(msg.getUserIds(), ";"));
            }
            broadcast(msg);
        }
        return weChartMessageRepository.save(msg);
    }

    @Override
    public JSONObject alarmMessage(AlarmMessageLog msg) {
        String text="%s报警：%s，%s系统发生%s,请及时核实处理反馈。";
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = String.format(text, msg.getAlarmType(), sdf.format(msg.getTime()), msg.getAlarmType(), msg.getArea());
        String accessToken = getAccessToken(weChatProperties.getCorpId(), weChatProperties.getCorpSecret());
        Map paramMap = new HashMap();
        paramMap.put("touser", msg.getToUsers());
        paramMap.put("agentid", weChatProperties.getAgentId());
        paramMap.put("text", new HashMap() {{
            put("content", format);
        }});
        paramMap.put("msgtype", "text");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        JSONObject jsonObject = new JSONObject(paramMap);
        HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), headers);
        JSONObject respnose = restTemplate.postForObject(String.format(weChatProperties.getSendMessageUrl(), accessToken), request, JSONObject.class);
        msg.setWeChartResponse(respnose.toJSONString());
        return respnose;
    }
    @Override
    public JSONObject wechatBaseMessage(WeChartBaseMessage msg) {
        String accessToken = getAccessToken(weChatProperties.getCorpId(), weChatProperties.getCorpSecret());
        Map paramMap = new HashMap();
        paramMap.put("touser", msg.getToUsers());
        paramMap.put("agentid", weChatProperties.getAgentId());
        paramMap.put("text", new HashMap() {{
            put("content", msg.getContent());
        }});
        paramMap.put("msgtype", "text");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        JSONObject jsonObject = new JSONObject(paramMap);
        HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), headers);
        JSONObject respnose = restTemplate.postForObject(String.format(weChatProperties.getSendMessageUrl(), accessToken), request, JSONObject.class);
        return respnose;
    }
    @Override
    public List<AlarmMessageItemVo> alarmMessageItem(String alarmType) {
        List<AlarmMessageItemVo> list=new ArrayList<>();
        if(StringUtils.isBlank(alarmType) || "安全监控".equals(alarmType)){
            R<List<AlarmMessageItemVo>> listR = remoteMonitorService.alarmMessageItem();
            if(listR.getCode()==200){
                if(listR.getData()!=null) {
                    list.addAll(listR.getData());
                }
            }
        }
        if(!"安全监控".equals(alarmType)){
            R<List<AlarmMessageItemVo>> listR = remoteEquipmentService.alarmMessageItem(alarmType);
            if(listR.getCode()==200){
                if(listR.getData()!=null) {
                    list.addAll(listR.getData());
                }
            }
        }

        return list;
    }

    private String getAccessToken(String corpid, String secret) {
        String weChat_access_token = RedisUtils.getCacheObject(ACCESS_TOKEN);
        if (weChat_access_token != null) {
            return weChat_access_token;
        }
        JSONObject forObject = restTemplate.getForObject(String.format(weChatProperties.getAccessTokenUrl(), corpid, secret), JSONObject.class);
        if ("0".equals(forObject.get("errcode") + "")) {
            weChat_access_token = forObject.getString("access_token");
        }
        RedisUtils.setCacheObject(ACCESS_TOKEN, weChat_access_token, Duration.ofMinutes(100l));
        return weChat_access_token;
    }

    private void broadcast(WeChartMessage msg) {

        String uuid = UUID.randomUUID().toString();
        String message = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<broadcast>\n" +
                "   <cmd>start</cmd>\n" +
                "   <uuid>" + uuid + "</uuid>\n" +
                "   <subject>" + msg.getEarlyWarnType() + "</subject>\n" +
                "   <cyclicmode>0</cyclicmode>\n" +
                "   <starttime></starttime>\n" +
                "   <misstime></misstime>\n" +
                "   <playloop>5</playloop>\n" +
                "   <contenttype>0</contenttype>\n" +
                "   <playcontent>" + msg.getEarlyWarnText() + "</playcontent>\n" +
                "   <members>" + msg.getToUsers() + "</members>\n" +
                "</broadcast>";
//                "<!--adapter msg end-->\n" +
//                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
//                "<broadcast>\n" +
//                "   <cmd>end</cmd>\n" +
//                "   <uuid>"+uuid+"</uuid>\n" +
//                "</broadcast>" +
//                "<!--adapter msg end-->";


        try {
            if (session == null) {
                MessageProcessor<String> processor = new MessageProcessor<String>() {
                    @Override
                    public void process(AioSession session, String message) {
//                        System.out.println("receive from server: " + message);
                        msg.setWeChartResponse(message);
//                    if(null != client){
//                        client.shutdown();
//                    }
                    }
                };
                client = new AioQuickClient("10.10.23.113", 6006, new DelimiterProtocol(), processor);

                session = client.start();
            }
            WriteBuffer writeBuffer = session.writeBuffer();
            byte[] data = message.getBytes();
//            client.setReadBufferSize(data.length);
            writeBuffer.writeInt(data.length);
            writeBuffer.write(data);
            writeBuffer.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
